package com.oron3.bouncer.genericgl;

import com.oron3.bouncer.interaction.AndroidInteractionInterpreter;
import com.oron3.bouncer.interaction.ClickListener;
import com.oron3.bouncer.interaction.MotionListener;
import com.oron3.bouncer.interaction.PressListener;
import com.oron3.bouncer.interaction.ZoomEvent;
import com.oron3.bouncer.interaction.ZoomListener;
import com.oron3.bouncer.objects.GLShape;
import com.oron3.bouncer.objects.shapes.Line;
import com.oron3.bouncer.objects.shapes.Point;

public abstract class GLWorld implements ClickListener, MotionListener, ZoomListener, PressListener ,Iterable<GLShape>{

	/**
	 * @param x
	 * @param y
	 * @return
	 */
	public Line convertScreenToWorld(final Point p) {
		final float[] screen = new float[4];
		final float[] world = new float[4];
		screen[0] = p.x;
		screen[1] = p.y;
		screen[2] = -1f;//0.95f;
		screen[3] = 1f;
		projector.unproject(screen, 0, world, 0);
		final Point p1 = new Point();
		p1.x = world[0];
		p1.y = world[1];
		p1.z = world[2];
		screen[0] = p.x;
		screen[1] = p.y;
		screen[2] = 1f;//0.95f;
		screen[3] = 1f;
		projector.unproject(screen, 0, world, 0);
		final Point p2 = new Point();
		p2.x = world[0];
		p2.y = world[1];
		p2.z = world[2];
		return new Line(p1,p2);
	}


	private Projector projector;
	private double zoomFactor = 1;


	/*
	 * (non-Javadoc)
	 * 
	 * @see com.oron3.bouncer.ZoomListener#onZoom(com.oron3.bouncer.ZoomEvent)
	 */
	@Override
	public boolean onZoom(final ZoomEvent e) {
		zoomFactor *= e.getZoomFactor();

		eyeDistance = (float) (zoomFactor * 100);
		return true;
	}

	public void setProjector(final Projector p) {
		projector = p;
	}

	public abstract void draw(final MatrixTrackingGL gl);

	/**
	 * @param a
	 */
	public void setInterpreter(final AndroidInteractionInterpreter a) {
		a.addListener(this);
	}

	protected Point eye = new Point();
	private float eyeDistance = 300;
	protected float rotationA = 0;
	protected float rotationB = 0;

	/**
	 * @return
	 */
	public Point getEye() {
		final float currentCam = (float) (eyeDistance * Math.cos((rotationA / 360) * 360 * Math.PI / 180.0));
		eye.z = (float) (eyeDistance * Math.sin((rotationA / 360) * 360 * Math.PI / 180.0));
		eye.y = (float) (currentCam * Math.sin((rotationB / 360) * 360 * Math.PI / 180.0));
		eye.x = (float) (currentCam * Math.cos((rotationB / 360) * 360 * Math.PI / 180.0));
		return eye;
	}

	/**
	 * @return
	 */
	public abstract Point getCenter();


}
